﻿using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using DevExpress.Utils.Menu;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Menu;
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraPrinting;
using RedRiver.Framework.XtraCommon.FormHelper;
using RedRiver.Framework.XtraCommon.Properties;

namespace RedRiver.Framework.XtraCommon.XtraControls{
    /// <summary>
    /// GridView菜单
    /// </summary>
    public class GridViewContextMenu : GridViewMenu{
        /// <summary>
        /// 默认实例
        /// </summary>
        private static GridViewContextMenu _instance;

        /// <summary>
        /// View Core Instance
        /// </summary>
        private static BaseView _instanceViewCore;

        public GridViewContextMenu(GridView view) : base(view){
            CreateItems();
        }

        public static GridViewContextMenu Instance{
            get{
                if (_instance == null){
                    _instance = new GridViewContextMenu(null){Caption = "表格操作(&G)", Image = Resources.GridControl};
                }
                return _instance;
            }
        }

        protected override BaseView ViewCore{
            get{
                if (base.ViewCore == null){
                    return _instanceViewCore;
                }
                return base.ViewCore;
            }
        }

        protected override sealed void CreateItems(){
            Items.Clear();
            Items.BeginUpdate();
            Items.Add(new GridExportMenu(View));
            Items.Add(new GridDataOperateMenu(View));
            Items.Add(new GridLayoutMenu(View));
            Items.Add(CreatePrintPreviewItem());
            Items.EndUpdate();
        }

        /// <summary>
        /// 初始化 表格帮助菜单
        /// <remarks>建议使用<see cref="GridControlUtils.InitGridViewHelper"/></remarks>
        /// </summary>
        /// <param name="gridControl"></param>
        public static void InitGridViewHelper(GridControl gridControl){
            AttachContextMenu(gridControl);
            RestoreGridViewLayout(gridControl.MainView);
        }

        /// <summary>
        /// 附加表格菜单    
        /// </summary>
        /// <param name="gridControl"></param>
        public static void AttachContextMenu(GridControl gridControl){
            foreach (BaseView view in gridControl.Views){
                if (view is GridView){
                    var gridView = (GridView) view;
                    gridView.PopupMenuShowing -= GridViewShowGridMenu;
                    gridView.PopupMenuShowing += GridViewShowGridMenu;
                }
            }
            gridControl.ViewRegistered += GridControlViewRegistered;
            gridControl.ViewRemoved += GridControlViewRemoved;
        }

        private static void GridControlViewRegistered(object sender, ViewOperationEventArgs e){
            if (e.View is GridView){
                var gridView = (GridView) e.View;
                gridView.PopupMenuShowing -= GridViewShowGridMenu;
                gridView.PopupMenuShowing += GridViewShowGridMenu;
            }
        }

        private static void GridControlViewRemoved(object sender, ViewOperationEventArgs e){}

        /// <summary>
        /// 显示GridView向下文菜单
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void GridViewShowGridMenu(object sender, PopupMenuShowingEventArgs e){
            var view = (GridView) sender;
            _instanceViewCore = view;
            if (e.Menu != null){
                e.Menu.Items.BeginUpdate();
                DXMenuItemCollection items = e.Menu.Items;
                if (e.MenuType ==
                    GridMenuType.Column){
                    var columnMenu = e.Menu as GridViewColumnMenu;
                    CreateFixColumnMenuItem(columnMenu);
                }

                Instance.Items[0].BeginGroup = true;
                foreach (DXMenuItem item in Instance.Items){
                    items.Add(item);
                }
                e.Menu.Items.EndUpdate();
            } else{
                Instance.Show(e.Point);
            }
        }

        #region FixColumnMenu

        /// <summary>
        /// 创建固定列菜单项
        /// </summary>
        /// <param name="columnMenu"></param>
        private static void CreateFixColumnMenuItem(GridViewColumnMenu columnMenu){
            if ((columnMenu != null) && (columnMenu.Column != null)){
                DXMenuItemCollection items = columnMenu.Items;
                GridColumn column = columnMenu.Column;
                items.Add(CreateFixColumnMenuItem("不固定列", column, FixedStyle.None, null, true));
                items.Add(CreateFixColumnMenuItem("固定到左侧", column, FixedStyle.Left, null, false));
                items.Add(CreateFixColumnMenuItem("固定到右侧", column, FixedStyle.Right, null, false));
            }
        }

        private static DXMenuCheckItem CreateFixColumnMenuItem(string caption, GridColumn column, FixedStyle style,
                                                               Image image, bool beginGroup){
            var item = new DXMenuCheckItem(caption, column.Fixed == style, image, OnGridColumnFixedClick)
                       {Tag = new ColumnFixtedStyleMenuInfo(column, style), BeginGroup = beginGroup};
            return item;
        }

        private static void OnGridColumnFixedClick(object sender, EventArgs e){
            var item = sender as DXMenuItem;
            if (item != null){
                var info = item.Tag as ColumnFixtedStyleMenuInfo;
                if (info == null){
                    return;
                }
                info.Column.Fixed = info.Style;
                if (info.Style !=
                    FixedStyle.None){
                    info.Column.AppearanceCell.BackColor = SystemColors.Control;
                } else{
                    info.Column.AppearanceCell.BackColor = Color.Empty;
                }
            }
        }

        /// <summary>
        /// 列固定类型菜单信息类
        /// </summary>
        private class ColumnFixtedStyleMenuInfo{
            public readonly GridColumn Column;
            public readonly FixedStyle Style;

            public ColumnFixtedStyleMenuInfo(GridColumn column, FixedStyle style){
                Column = column;
                Style = style;
            }
        }

        #endregion FixColumnMenu

        #region GridControl Export

        /*
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private DXMenuItem CreateGridExportItem(){
            var subMenu = new DXSubMenuItem("导出(&E)"){Image = Resources.Action_Export};
            subMenu.Items.BeginUpdate();
            foreach (ExportInfo exportItem in ExportInfos){
                var menuItem = new DXMenuItem(exportItem.DocumentName, ExportMenuItem_OnClick, exportItem.MenuItemImage)
                               {Tag = exportItem};
                subMenu.Items.Add(menuItem);
            }
            subMenu.Items.EndUpdate();
            return subMenu;
        }

        /// <summary>
        /// 由操作系统打开文件
        /// </summary>
        /// <param name="fileName"></param>
        private static void OpenExportedFile(string fileName){
            DialogResult result = XtraMessageBox.Show("是否打开文件?", "数据导出...", MessageBoxButtons.YesNo,
                                                      MessageBoxIcon.Question);
            if (DialogResult.Yes == result){
                try{
                    var process = new Process{
                                                 StartInfo =
                                                     {FileName = fileName, Verb = "Open", WindowStyle = ProcessWindowStyle.Normal}
                                             };
                    process.Start();
                } catch (Exception ex){
                    XtraMessageBox.Show("不能打开文件" + ex.Message, Application.ProductName, MessageBoxButtons.OK,
                                        MessageBoxIcon.Error);
                }
            }
        }

        #region Export Data
        
        /// <summary>
        /// 响应导出菜单项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        private void ExportMenuItem_OnClick(object sender, EventArgs args){
            var toolItem = (DXMenuItem) sender;
            if ((null != toolItem.Tag) &&
                (toolItem.Tag is ExportInfo)){
                var exportInfo = (ExportInfo) toolItem.Tag;
                //保存导出文件
                var dialog = new SaveFileDialog{
                                                   Title = "导出 " + exportInfo.DocumentName,
                                                   Filter = exportInfo.DocumentName + "|*." + exportInfo.FileExtension,
                                                   FileName = View.Name
                                               };
                if (dialog.ShowDialog() ==
                    DialogResult.OK){
                    ExportToEx(exportInfo, View, dialog.FileName);
                }
            }
        }

        private static void ExportToEx(ExportInfo exportInfo, BaseView exportView, string fileName){
            Cursor currentCursor = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;
            switch (exportInfo.ExportType){
                case GridViewExportType.Htm:
                    exportView.ExportToHtml(fileName);
                    break;
                case GridViewExportType.Mht:
                    exportView.ExportToHtml(fileName);
                    break;
                case GridViewExportType.Pdf:
                    exportView.ExportToPdf(fileName);
                    break;
                case GridViewExportType.Rtf:
                    exportView.ExportToRtf(fileName);
                    break;
                case GridViewExportType.Txt:
                    exportView.ExportToText(fileName);
                    break;
                case GridViewExportType.Xls:
                    exportView.ExportToXls(fileName);
                    break;
                case GridViewExportType.Xlsx:
                    exportView.ExportToXlsx(fileName);
                    break;
            }
            Cursor.Current = currentCursor;
            OpenExportedFile(fileName);
        }
        */

        #region Nested type: ExportInfo

        private class ExportInfo{
            public ExportInfo(string documentName, GridViewExportType exportType, Image menuItemImage){
                ExportType = exportType;
                DocumentName = documentName;
                FileExtension = Convert.ToString(exportType);
                MenuItemImage = menuItemImage;
            }

            /// <summary>
            /// 导出类型
            /// </summary>
            public GridViewExportType ExportType{
                get;
                private set;
            }

            /// <summary>
            /// 文件扩展名
            /// </summary>
            public string FileExtension{
                get;
                private set;
            }

            /// <summary>
            /// 文档名称
            /// </summary>
            public string DocumentName{
                get;
                private set;
            }

            /// <summary>
            /// 菜单项图片
            /// </summary>
            public Image MenuItemImage{
                get;
                private set;
            }
        }

        #endregion

        #region Nested type: GridViewExportType

        /// <summary>
        /// 导出文档类型
        /// </summary>
        internal enum GridViewExportType{
            [Description("RTF 文档")] Rtf,
            [Description("PDF 文档")] Pdf,
            [Description("单页 HTML 文档")] Mht,
            [Description("HTML 文档")] Htm,
            [Description("文本文档")] Txt,
            [Description("Excel 文档")] Xls,
            [Description("Excel X 文档")] Xlsx
        }

        #endregion

        #endregion GridControl Export

        #region GridControl 打印预览

        private DXMenuItem CreatePrintPreviewItem(){
            var printPreviewItem = new DXMenuItem("打印预览(&P)"){Image = Resources.Action_Printing_Preview};
            printPreviewItem.Click += PrintPreviewItem_Click;
            return printPreviewItem;
        }

        /// <summary>
        /// 打印预览
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PrintPreviewItem_Click(object sender, EventArgs e){
            View.GridControl.ShowPrintPreview();
        }

        #endregion GridControl 打印预览

        #region Static Methods

        private const string GridViewLayoutFolderName = "Layouts";

        /// <summary>
        /// 表格布局默认路径
        /// </summary>
        /// <returns></returns>
        private static string GetDefaultLayoutPath(){
            string path = Path.Combine(Application.UserAppDataPath, GridViewLayoutFolderName);
            if (!Directory.Exists(path)){
                Directory.CreateDirectory(path);
            }
            return path;
        }

        /// <summary>
        /// 获得默认布局文件名称
        /// </summary>
        /// <param name="view"></param>
        /// <returns></returns>
        private static string GetDefaultLayoutFileName(BaseView view){
            string formName = string.Empty;
            if (view == null){
                return ".layout";
            }
            if (view.GridControl != null){
                Form inForm = view.GridControl.FindForm();
                if (inForm != null){
                    formName = inForm.Text.Replace("*", string.Empty).Replace(" ", string.Empty);
                }
            }
            return string.Format("{0}_{1}.layout", formName, view.Name);
        }

        /// <summary>
        /// 保存表格布局到默认路径
        /// </summary>
        /// <param name="view"></param>
        public static void SaveGridViewLayout(BaseView view){
            string defaultPath = GetDefaultLayoutPath();
            if (!Directory.Exists(defaultPath)){
                Directory.CreateDirectory(defaultPath);
            }
            string fileName = Path.Combine(defaultPath, GetDefaultLayoutFileName(view));
            view.SaveLayoutToXml(fileName);
        }

        /// <summary>
        /// 从默认路径中查找对应的布局文件并恢复之
        /// </summary>
        /// <param name="view"></param>
        public static void RestoreGridViewLayout(BaseView view){
            string fileName = Path.Combine(GetDefaultLayoutPath(), GetDefaultLayoutFileName(view));
            if (File.Exists(fileName)){
                view.RestoreLayoutFromXml(fileName);
            }
        }

        #endregion Static Methods

        /*
        #region 数据操作菜单

        /// <summary>
        /// 表格数据操作菜单
        /// </summary>
        /// <returns></returns>
        private DXMenuItem CreateGridDataOperateItem(){
            var subMenu = new DXSubMenuItem("数据操作(&O)"){Image = Resources.Action_Inline_Edit};
            var loadDataItem = new DXMenuItem("加载数据(&L)", LoadData_OnClick, Resources.Action_Refresh);
            subMenu.Items.Add(loadDataItem);
            var saveGridData = new DXMenuItem("保存数据(&S)", SaveGridData_OnClick, Resources.Action_Save_To);
            subMenu.Items.Add(saveGridData);
            var copyToClipboardMenuItem = new DXMenuItem("复制(&C)", CopyToClipboard_OnClick, Resources.Action_Copy);
            subMenu.Items.Add(copyToClipboardMenuItem);
            var copyCellToClipboardMenuItem = new DXMenuItem("复制单元格(&E)", CopyCellToClipboard_OnClick,
                                                             Resources.Action_New);
            subMenu.Items.Add(copyCellToClipboardMenuItem);
            return subMenu;
        }

        /// <summary>
        /// 复制单元格
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CopyCellToClipboard_OnClick(object sender, EventArgs e){
            Clipboard.SetText(View.GetFocusedDisplayText());
        }

        /// <summary>
        /// 复制到剪贴板
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CopyToClipboard_OnClick(object sender, EventArgs e){
            View.CopyToClipboard();
        }

        /// <summary>
        /// 加载数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LoadData_OnClick(object sender, EventArgs e){
            DataSet dataSource = GetViewDataSource();
            if (dataSource != null){
                var dialog = new OpenFileDialog{
                                                   Title = "加载数据 " + dataSource.DataSetName,
                                                   Filter = "XML数据集文件|*.xml",
                                                   FileName = dataSource.DataSetName
                                               };
                if (dialog.ShowDialog() ==
                    DialogResult.OK){
                    dataSource.ReadXml(dialog.FileName);
                }
            }
        }

        /// <summary>
        /// 保存数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveGridData_OnClick(object sender, EventArgs e){
            DataSet dataSource = GetViewDataSource();
            if (dataSource != null){
                var dialog = new SaveFileDialog{
                                                   Title = "保存数据 " + dataSource.DataSetName,
                                                   Filter = "XML数据集文件|*.xml",
                                                   FileName = dataSource.DataSetName
                                               };
                if (dialog.ShowDialog() ==
                    DialogResult.OK){
                    dataSource.WriteXml(dialog.FileName);
                }
            }
        }

        private DataSet GetViewDataSource(){
            if ((View == null) ||
                (View.DataSource == null)){
                return null;
            }
            if (View.DataSource is DataTable){
                return ((DataTable) View.DataSource).DataSet;
            }
            if (View.DataSource is DataView){
                return ((DataView) View.DataSource).Table.DataSet;
            }
            if (View.DataSource is DataSet){
                return (DataSet) View.DataSource;
            }
            return null;
        }

        #endregion 数据操作菜单
        */

/*
        #region GridControl 布局操作

        /// <summary>
        /// GridControl 布局操作
        /// </summary>
        /// <returns></returns>
        private DXMenuItem CreateGridLayoutItem(){
            _gridLayoutSubMenuItem = new DXSubMenuItem("表格布局(&L)"){Image = Resources.Action_Chart_ShowDesigner};
            _gridLayoutSubMenuItem.BeforePopup += new EventHandler(GridLayoutSubMenuItemBeforePopup);
            _gridLayoutSubMenuItem.Items.Add(new DXMenuCheckItem("显示行号", false, Resources.Watermark,
                                                                 ShowRowNumberCheckChanged){Checked = false});
            _gridLayoutSubMenuItem.Items.Add(new DXMenuCheckItem("单元格合并", false, null, OnCellMergeChange));
            _gridLayoutSubMenuItem.Items.Add(new DXMenuItem("保存布局", SaveLayout_Click, Resources.Open));
            _gridLayoutSubMenuItem.Items.Add(new DXMenuItem("保存默认布局", SaveDefaultLayout_Click, Resources.ExportGraphic));
            _gridLayoutSubMenuItem.Items.Add(new DXMenuItem("加载布局", LoadLayout_Click, Resources.Save));
            return _gridLayoutSubMenuItem;
        }

        /// <summary>
        /// 菜单项展开时检查 子菜单 状态
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GridLayoutSubMenuItemBeforePopup(object sender, EventArgs e){
            var subMenu = (DXSubMenuItem) sender;
            foreach (DXMenuItem item in subMenu.Items){
                if (item.Caption.Equals("单元格合并")){
                    ((DXMenuCheckItem) item).Checked = View.OptionsView.AllowCellMerge;
                }
            }
        }

        /// <summary>
        /// 响应 单元格合并菜单 变更事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnCellMergeChange(object sender, EventArgs e){
            var checkItem = (DXMenuCheckItem) sender;
            View.OptionsView.AllowCellMerge = checkItem.Checked;
        }

        /// <summary>
        /// 响应 显示行号 菜单 选择状态变化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ShowRowNumberCheckChanged(object sender, EventArgs e){
            var checkItem = (DXMenuCheckItem) sender;
            GridControlUtils.ShowRowIndicatorIndex(View, checkItem.Checked);
        }

        /// <summary>
        /// 响应保存布局 菜单事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveLayout_Click(object sender, EventArgs e){
            var dialog = new SaveFileDialog{FileName = GetDefaultLayoutFileName(View), Filter = "布局文件|*.layout"};
            if (dialog.ShowDialog() ==
                DialogResult.OK){
                View.SaveLayoutToXml(dialog.FileName);
            }
        }

        /// <summary>
        /// 响应 保存默认布局  菜单事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveDefaultLayout_Click(object sender, EventArgs e){
            View.SaveLayoutToXml(Path.Combine(GetDefaultLayoutPath(), GetDefaultLayoutFileName(View)));
        }

        /// <summary>
        /// 响应 加载布局  菜单事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LoadLayout_Click(object sender, EventArgs e){
            var dialog = new OpenFileDialog{FileName = GetDefaultLayoutFileName(View), Filter = "布局文件|*.layout"};
            if (dialog.ShowDialog() ==
                DialogResult.OK){
                View.RestoreLayoutFromXml(dialog.FileName);
            }
        }

        #endregion  GridControl 布局操作
*/

        //#endregion Export Data

        #region Nested type: GridDataOperateMenu

        /// <summary>
        /// 表格数据操作菜单
        /// </summary>
        private class GridDataOperateMenu : GridViewMenu{
            public GridDataOperateMenu(GridView view) : base(view){
                Caption = "数据操作(&O)";
                Image = Resources.Action_Inline_Edit;
            }

            protected override BaseView ViewCore{
                get { return _instanceViewCore; }
            }

            protected override void OnBeforePopup(){
                base.OnBeforePopup();
                if (Items.Count == 0){
                    CreateItems();
                }
            }

            protected override void CreateItems(){
                Items.BeginUpdate();
                var loadDataItem = new DXMenuItem("加载数据(&L)", LoadData_OnClick, Resources.Action_Refresh);
                Items.Add(loadDataItem);
                var saveGridData = new DXMenuItem("保存数据(&S)", SaveGridData_OnClick, Resources.Action_Save_To);
                Items.Add(saveGridData);
                var copyToClipboardMenuItem = new DXMenuItem("复制(&C)", CopyToClipboard_OnClick, Resources.Action_Copy);
                Items.Add(copyToClipboardMenuItem);
                var copyCellToClipboardMenuItem = new DXMenuItem("复制单元格(&E)", CopyCellToClipboard_OnClick,
                                                                 Resources.Action_New);
                Items.Add(copyCellToClipboardMenuItem);
                Items.EndUpdate();
            }

            /// <summary>
            /// 复制单元格
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void CopyCellToClipboard_OnClick(object sender, EventArgs e){
                Clipboard.SetText(View.GetFocusedDisplayText());
            }

            /// <summary>
            /// 复制到剪贴板
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void CopyToClipboard_OnClick(object sender, EventArgs e){
                View.CopyToClipboard();
            }

            /// <summary>
            /// 加载数据
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void LoadData_OnClick(object sender, EventArgs e){
                DataSet dataSource = GetDataSource(View);
                if (dataSource != null){
                    var dialog = new OpenFileDialog{
                                                       Title = @"加载数据 " + dataSource.DataSetName,
                                                       Filter = @"XML数据集文件|*.xml",
                                                       FileName = dataSource.DataSetName
                                                   };
                    if (dialog.ShowDialog() ==
                        DialogResult.OK){
                        dataSource.ReadXml(dialog.FileName);
                    }
                }
            }

            /// <summary>
            /// 保存数据
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void SaveGridData_OnClick(object sender, EventArgs e){
                DataSet dataSource = GetDataSource(View);
                if (dataSource != null){
                    var dialog = new SaveFileDialog{
                                                       Title = @"保存数据 " + dataSource.DataSetName,
                                                       Filter = @"XML数据集文件|*.xml",
                                                       FileName = dataSource.DataSetName
                                                   };
                    if (dialog.ShowDialog() ==
                        DialogResult.OK){
                        dataSource.WriteXml(dialog.FileName);
                    }
                }
            }

            private static DataSet GetDataSource(BaseView gridView){
                if ((gridView == null) ||
                    (gridView.GridControl.DataSource == null)){
                    return null;
                }
                object dataSource = gridView.GridControl.DataSource;
                return GetDataSource(dataSource);
            }

            private static DataSet GetDataSource(object dataSource){
                if (dataSource is BindingSource){
                    return GetDataSource(((BindingSource) dataSource).DataSource);
                }
                if (dataSource is DataSet){
                    return (DataSet) dataSource;
                }

                if (dataSource is DataTable){
                    return ((DataTable) dataSource).DataSet;
                }
                if (dataSource is DataView){
                    return ((DataView) dataSource).Table.DataSet;
                }
                return null;
            }
        }

        #endregion

        #region Nested type: GridExportMenu

        /// <summary>
        /// 表格数据导出菜单
        /// </summary>
        private class GridExportMenu : GridViewMenu{
            /// <summary>
            /// 表格数据导出信息
            /// </summary>
            private static readonly ExportInfo[] ExportInfos = new[]{
                                                                        new ExportInfo("HTML 文档", GridViewExportType.Htm,
                                                                                       Resources.Action_Export_ToHTML),
                                                                        new ExportInfo("单页HTML文档",
                                                                                       GridViewExportType.Mht,
                                                                                       Resources.Action_Export_ToMHT),
                                                                        new ExportInfo("PDF 文档", GridViewExportType.Pdf,
                                                                                       Resources.Action_Export_ToPDF),
                                                                        new ExportInfo("RTF 文档", GridViewExportType.Rtf,
                                                                                       Resources.Action_Export_ToRTF),
                                                                        new ExportInfo("文本文档", GridViewExportType.Txt,
                                                                                       Resources.Action_Export_ToText),
                                                                        new ExportInfo("Excel 文档",
                                                                                       GridViewExportType.Xls,
                                                                                       Resources.Action_Export_ToExcel)
                                                                    };

            public GridExportMenu(GridView view) : base(view){
                Caption = "导出(&E)";
                Image = Resources.Action_Export;
            }

            protected override BaseView ViewCore{
                get { return _instanceViewCore; }
            }

            protected override void OnBeforePopup(){
                base.OnBeforePopup();
                if (Items.Count == 0){
                    CreateItems();
                }
            }

            protected override void CreateItems(){
                Items.BeginUpdate();
                foreach (ExportInfo exportItem in ExportInfos){
                    var menuItem = new DXMenuItem(exportItem.DocumentName, ExportMenuItem_OnClick,
                                                  exportItem.MenuItemImage){Tag = exportItem};
                    Items.Add(menuItem);
                }
                Items.EndUpdate();
            }

            /// <summary>
            /// 由操作系统打开文件
            /// </summary>
            /// <param name="fileName"></param>
            private static void OpenExportedFile(string fileName){
                DialogResult result = XtraMessageBox.Show("是否打开文件 "+ Path.GetFileName(fileName) +" ?", "数据导出...", MessageBoxButtons.YesNo,
                                                          MessageBoxIcon.Question);
                if (DialogResult.Yes == result){
                    try{
                        var process = new Process{
                                                     StartInfo ={
                                                                    FileName = fileName,
                                                                    Verb = "Open",
                                                                    WindowStyle = ProcessWindowStyle.Normal
                                                                }
                                                 };
                        process.Start();
                    } catch (Exception ex){
                        XtraMessageBox.Show("不能打开文件" + ex.Message, Application.ProductName, MessageBoxButtons.OK,
                                            MessageBoxIcon.Error);
                    }
                }
            }

            /// <summary>
            /// 响应导出菜单项
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="args"></param>
            private void ExportMenuItem_OnClick(object sender, EventArgs args){
                var toolItem = (DXMenuItem) sender;
                if ((null != toolItem.Tag) &&
                    (toolItem.Tag is ExportInfo)){
                    var exportInfo = (ExportInfo) toolItem.Tag;
                    //保存导出文件
                    var dialog = new SaveFileDialog{
                                                       Title = @"导出 " + exportInfo.DocumentName,
                                                       Filter =
                                                           exportInfo.DocumentName + @"|*." + exportInfo.FileExtension,
                                                       FileName = View.Name
                                                   };
                    if (dialog.ShowDialog() ==
                        DialogResult.OK){
                        ExportToEx(exportInfo, View, dialog.FileName);
                    }
                }
            }

            private static void ExportToEx(ExportInfo exportInfo, BaseView exportView, string fileName){
                if(exportView is GridView){
                    ((GridView) exportView).OptionsPrint.AutoWidth = false;
                }
                Cursor currentCursor = Cursor.Current;
                Cursor.Current = Cursors.WaitCursor;
                switch (exportInfo.ExportType){
                    case GridViewExportType.Htm:
                        exportView.ExportToHtml(fileName);
                        break;
                    case GridViewExportType.Mht:
                        exportView.ExportToMht(fileName);
                        break;
                    case GridViewExportType.Pdf:
                        exportView.ExportToPdf(fileName);
                        break;
                    case GridViewExportType.Rtf:
                        exportView.ExportToRtf(fileName);
                        break;
                    case GridViewExportType.Txt:
                        exportView.ExportToText(fileName);
                        break;
                    case GridViewExportType.Xls:
                        exportView.ExportToXls(fileName,new XlsExportOptions(TextExportMode.Value,true,false,true,true));
                        break;
                    case GridViewExportType.Xlsx:
                        exportView.ExportToXlsx(fileName, new XlsxExportOptions(TextExportMode.Value, true, false));
                        break;
                }
                Cursor.Current = currentCursor;
                OpenExportedFile(fileName);
            }
        }

        #endregion

        #region Nested type: GridLayoutMenu

        private class GridLayoutMenu : GridViewMenu{
            private DXMenuCheckItem _itemCellMerge;
            private DXMenuItem _itemLaodLayout;
            private DXMenuItem _itemSaveDefaultLayout;
            private DXMenuItem _itemSaveLayout;
            private DXMenuCheckItem _itemShowRowNumber;
            private DXMenuItem _itemRemoveDefaultLayout;

            public GridLayoutMenu(GridView view) : base(view){
                Image = Resources.Action_Chart_ShowDesigner;
                Caption = "表格布局(&L)";
            }

            protected override BaseView ViewCore{
                get { return _instanceViewCore; }
            }

            protected override void OnBeforePopup(){
                base.OnBeforePopup();
                if (Items.Count == 0){
                    CreateItems();
                }
                _itemCellMerge.Checked = View.OptionsView.AllowCellMerge;
                _itemShowRowNumber.Checked = GridControlUtils.GetRowIndicatorState(View);
            }

            protected override void CreateItems(){
                _itemShowRowNumber = new DXMenuCheckItem("显示行号", false, Resources.List_NumberedHS,
                                                         ShowRowNumberCheckChanged)
                                     {Checked = false};
                Items.Add(_itemShowRowNumber);
                _itemCellMerge = new DXMenuCheckItem("单元格合并", false, Resources.Action_CloneMerge_Merge_Object,
                                                     OnCellMergeChange);
                Items.Add(_itemCellMerge);
                _itemSaveLayout = new DXMenuItem("保存布局", SaveLayoutClick, Resources.Open);
                Items.Add(_itemSaveLayout);
                _itemSaveDefaultLayout = new DXMenuItem("保存默认布局", SaveDefaultLayoutClick, Resources.ExportGraphic);
                Items.Add(_itemSaveDefaultLayout);
                _itemRemoveDefaultLayout = new DXMenuItem("删除默认布局", RemoveDefaultLayoutClick, Resources.Action_Delete);
                Items.Add(_itemRemoveDefaultLayout);

                _itemLaodLayout = new DXMenuItem("加载布局", LoadLayoutClick, Resources.Save);
                Items.Add(_itemLaodLayout);
            }

            /// <summary>
            /// 清除默认布局,(当数据视图更新时,需要删除旧布局)
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void RemoveDefaultLayoutClick(object sender, EventArgs e){
                    var layoutPath = Path.Combine(GetDefaultLayoutPath(), GetDefaultLayoutFileName(View));
                    if(File.Exists(layoutPath)){
                        File.Delete(layoutPath);
                    }
            }

            /// <summary>
            /// 响应 单元格合并菜单 变更事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void OnCellMergeChange(object sender, EventArgs e){
                var checkItem = (DXMenuCheckItem) sender;
                View.OptionsView.AllowCellMerge = checkItem.Checked;
            }

            /// <summary>
            /// 响应 显示行号 菜单 选择状态变化
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void ShowRowNumberCheckChanged(object sender, EventArgs e){
                var checkItem = (DXMenuCheckItem) sender;
                GridControlUtils.ShowRowIndicatorIndex(View, checkItem.Checked);
            }

            /// <summary>
            /// 响应保存布局 菜单事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void SaveLayoutClick(object sender, EventArgs e){
                var dialog = new SaveFileDialog
                             {FileName = GetDefaultLayoutFileName(View), Filter = @"布局文件|*.layout", Title = @"保存表格布局"};
                if (dialog.ShowDialog() ==
                    DialogResult.OK){
                    View.SaveLayoutToXml(dialog.FileName);
                }
            }

            /// <summary>
            /// 响应 保存默认布局  菜单事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void SaveDefaultLayoutClick(object sender, EventArgs e){
                View.SaveLayoutToXml(Path.Combine(GetDefaultLayoutPath(), GetDefaultLayoutFileName(View)));
            }

            /// <summary>
            /// 响应 加载布局  菜单事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void LoadLayoutClick(object sender, EventArgs e){
                var dialog = new OpenFileDialog{
                                                   FileName = GetDefaultLayoutFileName(View),
                                                   Filter = @"布局文件|*.layout",
                                                   Title = @"选择需要加载的表格布局"
                                               };
                if (dialog.ShowDialog() ==
                    DialogResult.OK){
                    View.RestoreLayoutFromXml(dialog.FileName);
                }
            }
        }

        #endregion
    }
}